#pragma once

#include <vector>

enum filter_key
{
	FltKey_PID,
	FltKey_ProcessName,
	FltKey_ProcessPath,
	FltKey_EventPath,
	FltKey_Arch,
	FltKey_SessionId,
	FltKey_EventType,
	FltKey_EventClass,

	//Do not use this
	FltKey_Max, 
};
enum filter_rel
{
	FltRel_Is,
	FltRel_IsNot,
	FltRel_LargerThan,
	FltRel_SmallerThan,
	FltRel_Contain,
	FltRel_NotContain,
};

class CEventFilter
{
public:
	CEventFilter(filter_rel Relation, bool bInclude)
	{
		m_Relation = Relation;
		m_Include = bInclude;
	};
	virtual filter_key GetKey(void) = 0;
	virtual LPCWSTR GetDisplayValue(void) { return m_DisplayValue; }
	virtual bool DoFilter(CUniqueEvent *ev) = 0;
public:
	CString m_DisplayValue;
	filter_rel m_Relation;
	bool m_Include;
};

class CEventFilter_PID : public CEventFilter
{
public:
	CEventFilter_PID(DWORD ProcessId, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_ProcessId = ProcessId;
		m_DisplayValue.Format(L"%d", ProcessId);
	};

	virtual filter_key GetKey(void) { return FltKey_PID; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	DWORD m_ProcessId;
};

class CEventFilter_ProcessName : public CEventFilter
{
public:
	CEventFilter_ProcessName(LPCWSTR val, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_Str = val;
		m_DisplayValue = val;
	};

	virtual filter_key GetKey(void) { return FltKey_ProcessName; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	CString m_Str;
};

class CEventFilter_ProcessPath : public CEventFilter
{
public:
	CEventFilter_ProcessPath(LPCWSTR val, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_Str = val;
		m_DisplayValue = val;
	};

	virtual filter_key GetKey(void) { return FltKey_ProcessPath; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	CString m_Str;
};

class CEventFilter_EventPath : public CEventFilter
{
public:
	CEventFilter_EventPath(LPCWSTR val, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_Str = val;
		m_DisplayValue = val;
	};

	virtual filter_key GetKey(void) { return FltKey_EventPath; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	CString m_Str;
};

class CEventFilter_Arch : public CEventFilter
{
public:
	CEventFilter_Arch(bool bIs64Bit, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_bIs64Bit = bIs64Bit;
		m_DisplayValue = (bIs64Bit ? L"x64" : L"x86");
	};

	virtual filter_key GetKey(void) { return FltKey_Arch; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	bool m_bIs64Bit;
};

class CEventFilter_SessionId : public CEventFilter
{
public:
	CEventFilter_SessionId(DWORD SessionId, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_SessionId = SessionId;
		m_DisplayValue.Format(L"%d", SessionId);
	};

	virtual filter_key GetKey(void) { return FltKey_SessionId; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	DWORD m_SessionId;
};

class CEventFilter_EventType : public CEventFilter
{
public:
	CEventFilter_EventType(EventType_t eventType, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_EventType = eventType;
		m_DisplayValue = EventNameTable[eventType].eventName;
	};

	virtual filter_key GetKey(void) { return FltKey_EventType; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	EventType_t m_EventType;
};

class CEventFilter_EventClass : public CEventFilter
{
public:
	CEventFilter_EventClass(EventClass_t eventClass, filter_rel Relation, bool bInclude) : CEventFilter(Relation, bInclude)
	{
		m_EventClass = eventClass;
		m_DisplayValue = EventClassNameTable[eventClass].className;
	};

	virtual filter_key GetKey(void) { return FltKey_EventClass; }
	virtual bool DoFilter(CUniqueEvent *ev);
public:
	EventClass_t m_EventClass;
};

typedef std::vector<CEventFilter *> CFilterList;